<?php

	eb_include_class("EbSQLModel");
	eb_include_module_file("Core/ObjectVO");

	class ObjectModel extends EbSQLModel implements IModel
	{
		var $tablename;
		var $key;
		var $vomodulefile;
		
		public function __construct()
		{
			parent::init();
		}
				
		public function init($tablename,$vomodulefile = null,$key = null, $datasource = null)
		{
			$this->tablename = $tablename;
			$this->key = $key;
			$this->vomodulefile = $vomodulefile;
						
			parent::init($datasource);
		}
		
		public function getVO()
		{			
			if (is_null($this->vomodulefile))
			{
				return new stdClass();
			}
			else
			{
				return eb_module_file_new_instance($this->vomodulefile);
			}
		}
		
		public function getObjectColumns()
		{
			return array(
				new EbTableColumn("ob_id","int",false,EB_PRIMARY_KEY,true),
				new EbTableColumn("ob_type","tinyint",true,EB_INDEX_KEY),
				new EbTableColumn("name","varchar(64)"),
				new EbTableColumn("uuid","varchar(128)",true,EB_UNIQUE_KEY),
				new EbTableColumn("roles","varchar(32)",false,0x00,false),
				new EbTableColumn("urlname","varchar(128)"),
				new EbTableColumn("updated_at","datetime"),
				new EbTableColumn("created_at","datetime")
			);
		}
				
		public function create()
		{
			if (!is_null($this->tablename))
			{
				//parent::create('eb_objecttype');
				parent::create('eb_object',$this->getObjectColumns());
				
				//parent::insert('eb_objecttype',array('name' => $this->tablename));
				
				return parent::create($this->tablename,$this->getColumns());
			}
			else
			{
				return 0;
			}
		}
		
		public function insert($vo)
		{
			$vo = (object) $vo;
		
			$voObject = new ObjectVO();
			$voSub = new StdClass();
			
			foreach ($vo AS $key => $value)
			{
				if (property_exists($voObject,$key))
				{				
					$voObject->$key = $value;
				}
				else
				{
					$voSub->$key = $value;
				}
			}
			
			if (is_null($voObject->roles))
			{
				$voObject->roles = 1;
			}
			
			if (is_null($voObject->urlname))
			{
				$voObject->urlname = EbUrlRoutingToolkit::formatToUrl($voObject->name);
			}			
			
			if (is_null($voObject->uuid))
			{
				$voObject->uuid = eb_uuid();
			}
			
			$voObject->created_at = "NOW()";
			$voObject->updated_at = "NOW()";
			$voObject->ob_type = 0;//"SELECT COALESCE(ob_type,0) FROM eb_objecttype WHERE name = '".$this->table->getName()."'";
			
			$voSub->ob_id = $voObject->ob_id = parent::insert('eb_object',$voObject);
			
			$vo->ob_id = $voSub->ob_id;
			
			return parent::insert($this->tablename,$voSub);
		}
		
		public function select_()
		{
			parent::init();
			
			return $this->execute('SELECT * FROM eb_object');
		}
		
		public function __call($name, $arguments) 
		{
			$name = strtolower($name);
		
			if (strpos($name,'select') == 0)
			{
				$field = substr($name,8);
				
				if (($a = strpos($field,'_')) !== false)
				{
					$limit = substr($field,$a+1);
					$field = substr($field,0,$a);
					
					if (!is_numeric($limit))
					{
						$field = substr($name,8);
						$limit = 0;
					}
				}
				else
				{
					$limit = 0;
				}

				if ($field === 'id')
				{
					$field = $this->key;
					
					$buffer = $this->select("$field = ".$arguments[0]);
				}
				else
				{
					$buffer = $this->select("$field = '".$arguments[0]."'");
				}
				
				if ($limit == 1)
				{
					return count($buffer) == 1 ? $buffer[0] : null;
				}
				else
				{
					return $buffer;
				}
			}
			
//			if (strpos($name,"select") == 0)
//			{
//				$field = substr($name,strlen("selectby"));
//				
//				if ($field == "id")
//				{	
//					if (count($arguments) == 1)
//					{					
//						return $this->select("$this->key = ".$arguments[0]);
//					}
//					else
//					{
//						return $this->select("$this->key IN (".implode(',',$arguments).')');
//					}
//				}
//				else
//				{
//					if (count($arguments) == 1 || !is_null($arguments[1]))
//					{					
//						return $this->select("$field = '".$arguments[0]."'");
//					}
//					else
//					{
//						return $this->select("$field = '".$arguments[0]."' $arguments[1]");
//					}
//				}
//			}
		}			
		
		public function select($whereClause = null, $orderClause = null)
		{
			$sql = 'SELECT * FROM '.$this->tablename.' INNER JOIN eb_object ON eb_object.ob_id = '.$this->tablename.'.ob_id ';
			
			if (!is_null($whereClause) && strlen($whereClause) > 0)
			{
				$sql.= " WHERE $whereClause";
			}
			
			if (!is_null($orderClause) && strlen($orderClause) > 0)
			{
				$sql.= " ORDER BY $orderClause";
			}			
						
			return $this->executeSelectQuery($sql);
		}
		
		public function executeSelectQuery($sql)
		{		
			$results = $this->datasource->execute($sql);
						
			if (is_null($results) || $results === false)
			{
				return array();
			}
			else
			{
				$buffer = array();
				
				foreach ($results AS $result)
				{
					$newVo = $this->getVO();
					
					foreach($newVo as $key => &$value) 
					{
						if (isset($result->$key))
						{
							$value = $result->$key;
						}
						else
						{
							
						}
					}
					
					$buffer []= $newVo;
				}
				
				return $buffer;
			}
		}
		
		public function update($vo)
		{
			$vo = (Object) $vo;
			$key = $this->key;
			
			if (!isset($vo->$key))
			{
				throw new Exception('You must define the key "'.$key.'" in the object you want to update!');
			}
		
			$object = new ObjectVO();
			
			$voObject = new StdClass();
			$voSub = new StdClass();
			
			foreach ($vo AS $k => $v)
			{
				if (property_exists($object,$k))
				{				
					$voObject->$k = $v;
				}
				else
				{
					$voSub->$k = $v;
				}
			}
			
			$voObject->updated_at = 'NOW()';
						
			parent::update('eb_object',$voObject,'ob_id = (SELECT ob_id FROM '.$this->tablename.' WHERE '.$key.'='.$vo->$key.')');
			
			return parent::update($this->tablename,$voSub,$key.'='.$vo->$key);
		}
				
		public function delete($vo)
		{
			if (is_numeric($vo))
			{
				$id = $vo; 
			}
			else
			{
				$key = $this->key;
				$id = $vo->$key;
			}
			
			$sql = 'DELETE FROM eb_object WHERE ob_id = (SELECT ob_id FROM '.$this->tablename.' WHERE '.$this->key.'='.$id.')';
			
			$this->execute($sql);
			
			$sql = 'DELETE FROM '.$this->tablename.' WHERE '.$this->key.' = '.$id;
			
			return $this->execute($sql);
		}		
	
	}